{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模块导入"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Variable"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们导入Variable类。将tensor封装成了这种形式，然后就可以使用Variable的自动求导和反向传播功能了。普通的tensor是没有自动求导的\n",
    "\n",
    "variable和tensor几乎有一样的接口。方法都通用的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.autograd import Variable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1., 1.],\n",
       "        [1., 1., 1.]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = Variable(torch.ones(2,3))\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1., 1.],\n",
       "        [1., 1., 1.]], requires_grad=True)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.requires_grad_()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = x ** 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "grad can be implicitly created only for scalar outputs",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m--------------------------------------------------\u001b[0m",
      "\u001b[0;31mRuntimeError\u001b[0m     Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-8-ab75bb780f4c>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m~/miniconda3/lib/python3.8/site-packages/torch/tensor.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(self, gradient, retain_graph, create_graph)\u001b[0m\n\u001b[1;32m    183\u001b[0m                 \u001b[0mproducts\u001b[0m\u001b[0;34m.\u001b[0m \u001b[0mDefaults\u001b[0m \u001b[0mto\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    184\u001b[0m         \"\"\"\n\u001b[0;32m--> 185\u001b[0;31m         \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautograd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgradient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    186\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    187\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mregister_hook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/lib/python3.8/site-packages/torch/autograd/__init__.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables)\u001b[0m\n\u001b[1;32m    119\u001b[0m         \u001b[0mgrad_tensors\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgrad_tensors\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    120\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 121\u001b[0;31m     \u001b[0mgrad_tensors\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_make_grads\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtensors\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgrad_tensors\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    122\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mretain_graph\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    123\u001b[0m         \u001b[0mretain_graph\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/lib/python3.8/site-packages/torch/autograd/__init__.py\u001b[0m in \u001b[0;36m_make_grads\u001b[0;34m(outputs, grads)\u001b[0m\n\u001b[1;32m     45\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequires_grad\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     46\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnumel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 47\u001b[0;31m                     \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"grad can be implicitly created only for scalar outputs\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     48\u001b[0m                 \u001b[0mnew_grads\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mones_like\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmemory_format\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpreserve_format\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     49\u001b[0m             \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mRuntimeError\u001b[0m: grad can be implicitly created only for scalar outputs"
     ]
    }
   ],
   "source": [
    "y.backward()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 上面报错了，使用下面解决。但是为什么呢？\n",
    "y.backward(torch.ones_like(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[2., 2., 2.],\n",
       "        [2., 2., 2.]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.grad"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# torch.nn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果直接使用Variable来写神经网络，还是会有些吃力的。所以pytorch已经帮我们集成好了模块\n",
    "\n",
    "torch.nn 就是专门构建神经网络的模块，nn模块是基于自动求导之上的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = torch.randn(2,3,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[-0.0777,  0.6543,  1.1552],\n",
       "         [-1.6895,  1.5919, -0.4372],\n",
       "         [ 0.5987,  0.5051, -1.8900]],\n",
       "\n",
       "        [[-0.8786,  0.0778, -1.1554],\n",
       "         [-0.8521,  1.3059, -0.7968],\n",
       "         [ 0.4149, -1.4787, -0.7642]]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-0.0777,  0.6543,  1.1552],\n",
       "        [-1.6895,  1.5919, -0.4372],\n",
       "        [ 0.5987,  0.5051, -1.8900]])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[0,...]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-0.0777,  0.6543,  1.1552],\n",
       "        [-1.6895,  1.5919, -0.4372],\n",
       "        [ 0.5987,  0.5051, -1.8900]])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[0,:,:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[False,  True,  True],\n",
       "         [False,  True, False],\n",
       "         [ True,  True, False]],\n",
       "\n",
       "        [[False,  True, False],\n",
       "         [False,  True, False],\n",
       "         [ True, False, False]]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a > 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.6543, 1.1552, 1.5919, 0.5987, 0.5051, 0.0778, 1.3059, 0.4149])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[a>0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# autograd"
   ]
  },
  {
   "attachments": {
    "image.png": {
     "image/png": "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"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们来看一个函数\n",
    "\n",
    "![image.png](attachment:image.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "def func(x):\n",
    "    return x**2 * torch.exp(x)\n",
    "\n",
    "def pfunc(x):\n",
    "    return 2*x*torch.exp(x) + x**2 * torch.exp(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.autograd import Variable"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.0187, 0.4892, 0.8931, 0.5635],\n",
       "        [0.9389, 0.8019, 0.2144, 0.6179],\n",
       "        [0.6671, 0.7510, 0.1432, 0.4122]], requires_grad=True)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = Variable(torch.rand(3,4), requires_grad=True)\n",
    "# x.requires_grad_()\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = func(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "y.backward(torch.ones_like(x)) # 这里一定要设置形式像要求导的x一样"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.0385, 1.9859, 6.3121, 2.5381],\n",
       "        [7.0553, 5.0098, 0.5882, 3.0007],\n",
       "        [3.4665, 4.3786, 0.3542, 1.5015]])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.0385, 1.9859, 6.3121, 2.5381],\n",
       "        [7.0553, 5.0098, 0.5882, 3.0007],\n",
       "        [3.4665, 4.3786, 0.3542, 1.5015]], grad_fn=<AddBackward0>)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pfunc(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**我们可以看到这两个反向求导和手动求导的结果差不多**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 问题说明"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 内存共享"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "tensor的存储形式，分为信息区和数据区。信息区是存放数据的一些特点，比如shape这些\n",
    "\n",
    "有些操作会让内存空间共享\n",
    "\n",
    "在pytorch和numpy中，两个内存是共享的。所以可以相互转换。而且两者转换的开销非常小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = torch.rand(2,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.6505, 0.6190],\n",
       "        [0.8282, 0.8781]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = a.view(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.6505, 0.6190, 0.8282, 0.8781])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "b[1] = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.6505, 0.0000, 0.8282, 0.8781])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.6505, 0.0000],\n",
       "        [0.8282, 0.8781]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 可以发现a，b的存储信息区不是共享的，但是数据是共享的\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = a.numpy()\n",
    "# 下面两种方式转换成tensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = torch.from_numpy(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = torch.Tensor(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有些操作会使得数据不共享"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据连续性问题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "转置操作会使得数据变得不连续，无法进行view等操作\n",
    "\n",
    "所以使用下面方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.4807, 0.0078, 0.4733],\n",
       "        [0.7317, 0.4364, 0.9317]])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = torch.rand(2,3)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = a.t()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.4807, 0.7317],\n",
       "        [0.0078, 0.4364],\n",
       "        [0.4733, 0.9317]])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "a[0,0] = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.0000, 0.0078, 0.4733],\n",
       "        [0.7317, 0.4364, 0.9317]])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m--------------------------------------------------\u001b[0m",
      "\u001b[0;31mRuntimeError\u001b[0m     Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-54-3e8b85006291>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mview\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mRuntimeError\u001b[0m: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead."
     ]
    }
   ],
   "source": [
    "b.view(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.0000, 0.7317],\n",
       "        [0.0078, 0.4364],\n",
       "        [0.4733, 0.9317]])"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 因为b的数据是不连续的，所以不能使用view操作\n",
    "b.contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "b = b.contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1.0000, 0.7317, 0.0078, 0.4364, 0.4733, 0.9317])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.view(-1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 广播法则"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.],\n",
       "        [1.]])"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = torch.ones(2,1)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[0., 0.],\n",
       "         [0., 0.]],\n",
       "\n",
       "        [[0., 0.],\n",
       "         [0., 0.]]])"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = torch.zeros(2,2,2)\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 2, 2])"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res = a + b\n",
    "res.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[1., 1.],\n",
       "         [1., 1.]],\n",
       "\n",
       "        [[1., 1.],\n",
       "         [1., 1.]]])"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([1, 2, 1])"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 可以发现本来a和b的维度是不一样的，但是两者还是可以相加的\n",
    "# a是2维，b是3维\n",
    "# 拓展的规则是这样的：首先找到维度比较低的维度。将维度低的tensor拓展到维度比较高的\n",
    "a.unsqueeze(0).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[1., 1.],\n",
       "         [1., 1.]],\n",
       "\n",
       "        [[1., 1.],\n",
       "         [1., 1.]]])"
      ]
     },
     "execution_count": 94,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 虽然拓展了，但是两个维度的量还是不一样，另外两个都是2.而本来的是1\n",
    "# 然后通过expand手动拓展到相同。\n",
    "# 广播机制就像下面的操作一样\n",
    "\n",
    "a.unsqueeze(0).expand(2,2,2)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
